// JsonUtil.java
package com.dpl.yyrj.utils;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;

import java.lang.reflect.Type;

/**
 * @author dpl
 * @date: 2025/8/2 星期六 18:09
 * @description json 工具类
 **/
public class JsonUtil {

    private static final Gson gson = new Gson();

    /**
     * 将对象转换为JSON字符串
     *
     * @param object 要转换的对象
     * @return JSON字符串
     */
    public static String toJson(Object object) {
        try {
            return gson.toJson(object);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将JSON字符串转换为指定类型的对象
     *
     * @param json     JSON字符串
     * @param classOfT 目标类的Class对象
     * @param <T>      目标类型
     * @return 转换后的对象
     */
    public static <T> T fromJson(String json, Class<T> classOfT) {
        try {
            return gson.fromJson(json, classOfT);
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将JSON字符串转换为List对象
     *
     * @param json JSON字符串
     * @param type TypeToken类型
     * @param <T>  目标类型
     * @return 转换后的List对象
     */
    public static <T> T fromJson(String json, Type type) {
        try {
            return gson.fromJson(json, type);
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查询JSON对象中的值
     *
     * @param json JSON字符串
     * @param key  要查询的键
     * @return 查询到的值，如果不存在返回null
     */
    public static JsonElement queryValue(String json, String key) {
        try {
            JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
            return queryValueRecursive(jsonObject, key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 递归查询JSON对象中的值
     *
     * @param jsonObject JSON对象
     * @param key        要查询的键
     * @return 查询到的值，如果不存在返回null
     */
    private static JsonElement queryValueRecursive(JsonObject jsonObject, String key) {
        if (jsonObject.has(key)) {
            return jsonObject.get(key);
        }

        // 递归查找嵌套对象
        for (String k : jsonObject.keySet()) {
            JsonElement element = jsonObject.get(k);
            if (element.isJsonObject()) {
                JsonElement result = queryValueRecursive(element.getAsJsonObject(), key);
                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

    /**
     * 查询JSON数组中的元素
     *
     * @param json  JSON字符串
     * @param index 数组索引
     * @return 查询到的元素，如果不存在返回null
     */
    public static JsonElement queryArrayElement(String json, int index) {
        try {
            JsonArray jsonArray = JsonParser.parseString(json).getAsJsonArray();
            if (index >= 0 && index < jsonArray.size()) {
                return jsonArray.get(index);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 在JSON对象中插入或更新键值对
     *
     * @param json  原始JSON字符串
     * @param key   键
     * @param value 值
     * @return 更新后的JSON字符串
     */
    public static String insertKeyValue(String json, String key, Object value) {
        try {
            JsonObject jsonObject;
            if (json == null || json.trim().isEmpty()) {
                jsonObject = new JsonObject();
            } else {
                jsonObject = JsonParser.parseString(json).getAsJsonObject();
            }

            if (value == null) {
                jsonObject.remove(key);
            } else if (value instanceof String) {
                jsonObject.addProperty(key, (String) value);
            } else if (value instanceof Number) {
                jsonObject.addProperty(key, (Number) value);
            } else if (value instanceof Boolean) {
                jsonObject.addProperty(key, (Boolean) value);
            } else if (value instanceof Character) {
                jsonObject.addProperty(key, (Character) value);
            } else {
                jsonObject.add(key, gson.toJsonTree(value));
            }

            return gson.toJson(jsonObject);
        } catch (Exception e) {
            e.printStackTrace();
            return json;
        }
    }

    /**
     * 在JSON数组中插入元素
     *
     * @param json  原始JSON字符串
     * @param value 要插入的值
     * @return 更新后的JSON字符串
     */
    public static String insertArrayElement(String json, Object value) {
        try {
            JsonArray jsonArray;
            if (json == null || json.trim().isEmpty()) {
                jsonArray = new JsonArray();
            } else {
                jsonArray = JsonParser.parseString(json).getAsJsonArray();
            }

            if (value == null) {
                jsonArray.add((String) null);
            } else if (value instanceof String) {
                jsonArray.add((String) value);
            } else if (value instanceof Number) {
                jsonArray.add((Number) value);
            } else if (value instanceof Boolean) {
                jsonArray.add((Boolean) value);
            } else if (value instanceof Character) {
                jsonArray.add((Character) value);
            } else {
                jsonArray.add(gson.toJsonTree(value));
            }

            return gson.toJson(jsonArray);
        } catch (Exception e) {
            e.printStackTrace();
            return json;
        }
    }

    /**
     * 在JSON数组指定位置插入元素
     *
     * @param json  原始JSON字符串
     * @param index 插入位置
     * @param value 要插入的值
     * @return 更新后的JSON字符串
     */
    public static String insertArrayElement(String json, int index, Object value) {
        try {
            JsonArray jsonArray;
            if (json == null || json.trim().isEmpty()) {
                jsonArray = new JsonArray();
            } else {
                jsonArray = JsonParser.parseString(json).getAsJsonArray();
            }

            // 确保数组长度足够
            while (jsonArray.size() < index) {
                jsonArray.add((String) null);
            }

            JsonElement element;
            if (value == null) {
                element = gson.toJsonTree(null);
            } else if (value instanceof String) {
                element = gson.toJsonTree(value, String.class);
            } else if (value instanceof Number) {
                element = gson.toJsonTree(value, Number.class);
            } else if (value instanceof Boolean) {
                element = gson.toJsonTree(value, Boolean.class);
            } else if (value instanceof Character) {
                element = gson.toJsonTree(value, Character.class);
            } else {
                element = gson.toJsonTree(value);
            }

            if (index < jsonArray.size()) {
                jsonArray.set(index, element);
            } else {
                jsonArray.add(element);
            }

            return gson.toJson(jsonArray);
        } catch (Exception e) {
            e.printStackTrace();
            return json;
        }
    }

    /**
     * 从JSON对象中删除指定键
     *
     * @param json 原始JSON字符串
     * @param key  要删除的键
     * @return 更新后的JSON字符串
     */
    public static String removeKey(String json, String key) {
        try {
            JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
            jsonObject.remove(key);
            return gson.toJson(jsonObject);
        } catch (Exception e) {
            e.printStackTrace();
            return json;
        }
    }

    /**
     * 从JSON数组中删除指定索引的元素
     *
     * @param json  原始JSON字符串
     * @param index 要删除的元素索引
     * @return 更新后的JSON字符串
     */
    public static String removeArrayElement(String json, int index) {
        try {
            JsonArray jsonArray = JsonParser.parseString(json).getAsJsonArray();
            if (index >= 0 && index < jsonArray.size()) {
                jsonArray.remove(index);
            }
            return gson.toJson(jsonArray);
        } catch (Exception e) {
            e.printStackTrace();
            return json;
        }
    }

    // 判断字符串是否为有效的JsonObject格式
    public static boolean isJson(String todayJson) {
        if (todayJson == null || todayJson.trim().isEmpty()) {
            return false;
        }
        try {
            JsonElement jsonElement = JsonParser.parseString(todayJson);
            return jsonElement.isJsonObject();
        } catch (Exception e) {
            return false;
        }
    }

    // 判断字符串是否为有效的JsonObject格式
    public static boolean isJsonArray(String todayJson) {
        if (todayJson == null || todayJson.trim().isEmpty()) {
            return false;
        }
        try {
            JsonElement jsonElement = JsonParser.parseString(todayJson);
            return jsonElement.isJsonArray();
        } catch (Exception e) {
            return false;
        }
    }

    public static String getJsonByMMKVKey(String mmkvKey) {
        String string = MMKVUtil.getString(mmkvKey, "");
        if (!isJson(string)) {
            string = "{}";
        }
        return string;
    }

    public static String getJsonArrayByMMKVKey(String mmkvKey) {
        String string = MMKVUtil.getString(mmkvKey, "");
        if (!isJsonArray(string)) {
            string = "[]";
        }
        return string;
    }

    /**
     * 更新JSON数组中指定位置的元素并返回新的JSON字符串
     *
     * @param currentJson 原始JSON数组字符串
     * @param jsonObject  要更新的JSON对象
     * @param position    要更新的位置
     * @return 更新后的JSON数组字符串
     */
    public static String upDateArrayElement(String currentJson, JsonObject jsonObject, int position) {
        try {
            JsonArray jsonArray = JsonParser.parseString(currentJson).getAsJsonArray();
            if (position >= 0 && position < jsonArray.size()) {
                jsonArray.set(position, jsonObject);
            } else {
                // 如果位置超出范围，可以选择添加到末尾或者抛出异常
                jsonArray.add(jsonObject);
            }
            return gson.toJson(jsonArray);
        } catch (Exception e) {
            e.printStackTrace();
            return currentJson;
        }
    }
}
